#※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
# File Name: base.sh
# Author: GID5564
# Description:
# Created Time: 06/11/23-20:18:14
#※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
#! /usr/bin/env bash

#########################################
#♥重要声明:  因个人习惯，如果函数使用echo返回0或1，此时0表明不肯定、否,1表示肯定、是; 如果函数使用return返回0或1则与shell相同。请注意区分。
#########################################

# 避免重复导入
#[[ -n $__XLIB_IMPORTED__BASE ]] && return 0
#__XLIB_IMPORTED__BASE=1

function __base_init__() {
    #颜色名称列表，待添加中…
    export COLORS_NAME="aliceblue antiquewhite aqua aquamarine azure beige bisque black blanchedalmond blue blueviolet brown burlywood cadetblue chartreuse chocolate coral cornflowerblue cornsilk crimson cyan darkblue darkcyan darkgoldenrod darkgray darkgreen darkkhaki darkmagenta darkolivegreen darkorange darkorchid darkred darksalmon darkseagreen darkslateblue darkslategray darkturquoise darkviolet deeppink deepskyblue dimgray dodgerblue firebrick floralwhite forestgreen fuchsia gainsboro ghostwhite gold goldenrod gray green greenyellow honeydew hotpink indianred indigo ivory khaki lavender lavenderblush lawngreen lemonchiffon lightblue lightcoral lightcyan lightgoldenrodyellow lightgreen lightgray lightpink lightsalmon lightseagreen lightskyblue lightslategray lightsteelblue lightyellow lime limegreen linen magenta maroon mediumaquamarine mediumblue mediumorchid mediumpurple mediumseagreen mediumslateblue mediumspringgreen mediumturquoise mediumvioletred midnightblue mintcream mistyrose moccasin navajowhite navy oldlace olive olivedrab orange orangered orchid palegoldenrod palegreen paleturquoise palevioletred papayawhip peachpuff peru pink plum powderblue purple red rosybrown royalblue saddlebrown salmon sandybrown seagreen seashell sienna silver skyblue slateblue slategray snow springgreen steelblue tan teal thistle tomato turquoise violet wheat white whitesmoke yellow yellowgreen"
}

#♦判断函数
########################################
# 描述: 判断变量是否为数组
# 参数: $1:变量 
# 返回: 1: 是；
#         0: 否
# 实例: IsArray <变量名>
########################################
function IsArray() {
    [[ -z "$1" ]] && {
        error "Usage: IsArray <variable name>"
        return $INVALID_ARGUMENTS
    }

    # 注意传递变量的作用域问题,在下面加了'-g'
    local ret=$(declare -p $1 2>/dev/null | grep -iE '^(typeset|declare) \-g \-a' | wc -l)
    echo $ret
    unset ret
}

########################################
# 描述: 判断文件后缀是否是指定后缀
# 参数: $1:文件名 $2:后缀名
# 返回: 1: 表示文件后缀是指定后缀；
#         0: 表示文件后缀不是指定后缀
# 实例: IsSuffix "xxxx.xxx" "xxx"
########################################
function IsSuffix() {
    [[ -z "$1" ]] && {
        error "Usage: IsSuffix <file> <suffix>"
        return $INVALID_ARGUMENTS
    }

    if [[ "${1##*.}" = "$2" ]]; then
        echo 1
    else
        echo 0
    fi
}
########################################
# 描述: 判断串中是否有汉字
# 参数: $1,文本字符串
# 返回: 1,有;0,没有
# 实例: hasHZ "nnm测gh试df字u符dd串"
########################################
function hasHZ(){
    [[ -z "$1" ]] && {
        error "Usage: IsHZ <string>"
        return $INVALID_ARGUMENTS
    }

    echo $(echo "${1}" | grep -P "[\p{Han}]+" | wc -l)
}
########################################
# 描述: 判断字符是否是汉字
# 参数: $1,文本字符串
# 返回: 1,是;0,否
# 实例: IsHZ "n"
########################################
function IsHZ(){
    [[ -z "$1" ]] && {
        error "Usage: IsHZ <char>"
        return $INVALID_ARGUMENTS
    }
    [[ ${#1} -gt 1 ]] && {
        error "Usage: IsHZ <char>, <char> is a single character!"
        return $INVALID_ARGUMENTS
    }

    echo $(echo ${1} | grep -P "[\p{Han}]+" | wc -l)
}

########################################
# 描述: 判断字符/串是否为数字
# 参数: $1:字符/串
# 返回: 1: 数字；
#       0: 字符/串
# 实例: IsDigit "x.xxx"
#       IsNumber "xxx"
########################################
function IsDigit() {
    #整数，浮点数
    [[ -z "$1" ]] && {
        error "Usage: IsDigit <integer|float>"
        return $INVALID_ARGUMENTS
    }

    echo "$1" | grep -qE '^[0-9]+([.][0-9]+)?$' && echo 1 || echo 0
}

function IsNumber(){
    [[ -z "$1" ]] && {
        error "Usage: IsNumber <integer>"
        return $INVALID_ARGUMENTS
    }

    local re='^[0-9]+$'
    if [[ ${1} =~ ${re} ]];then
        echo 1 #是数字
    else
        echo 0 #不是数字
    fi
	unset re
}
########################################
# 描述: 检测文件完整路径
# 参数: $1:路径字符串，如:
            #"https://www.ddd.ccc/home/aidboot/for.jpg"
            #"/home/aidboot/for.jpg"
# 返回: 1: 合理；
#       0: 不合理
# 实例: IsFullPath "xxx"
########################################
function IsFullPath(){
    [[ -z "$1" ]] && {
        error "Usage: IsFullPath <path>"
        return $INVALID_ARGUMENTS
    }

    local re='^(/|https?://)[^/]+(/.*)$'
    if [[ ${1} =~ ${re} ]];then
        echo 1 #是
    else
        echo 0 #不是
    fi
	unset re
}

########################################
# 描述: 字符串为空
# 参数: $1:字符/串
# 返回: 1: 为空；
#       0: 不为空
# 实例: IsEmpty "xxx"
########################################
function IsEmpty(){
    [[ -z "$1" ]] && {
        error "Usage: IsEmpty <string>"
        return $INVALID_ARGUMENTS
    }

    local str=${1// /} #防止整串都是空格
    if [[ -z ${str} ]];then
        echo 1
    else 
        echo 0
    fi
    unset str
}
########################################
# 描述: 字符串是否是合理邮箱格式
# 参数: $1:串
# 返回: 1: 是；
#       0: 不是
# 实例: IsEMail "xxx@xxxx.xxx"
########################################
function IsEMail(){
    [[ -z "$1" ]] && {
        error "Usage: IsEMail <email>"
        return $INVALID_ARGUMENTS
    }
    local re='^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
    if [[ ${s1} =~ ${re} ]];then
	    echo 1
	else
	    echo 0
	fi
	unset re
}
########################################
# 描述: 字符串是否是合理链接地址
# 参数: $1:串
# 返回: 1: 是；
#       0: 不是
# 实例: IsLink "xxx@xxxx.xxx"
########################################
function IsLink(){
    [[ -z "$1" ]] && {
        error "Usage: IsLink <url>"
        return $INVALID_ARGUMENTS
    }

    local re='^(f|ht){1}(tp|tps):\/\/((\w+)\.){0,3}(\w+)(\/(\w+))*'
    if [[ ${1} =~ ${re} ]];then
	    echo 1
	else
	    echo 0
	fi
	unset re
}
########################################
# 描述: 字符串是否是合理ip地址
# 参数: $1:串
# 返回: 1: 是；
#       0: 不是
# 实例: IsIP "xxx.xxx.xxx.xxx"
########################################
function IsIP(){
    [[ -z "$1" ]] && {
        error "Usage: IsIP <ip-adress>"
        return $INVALID_ARGUMENTS
    }
    local re='^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$'
    if [[ ${1} =~ ${re} ]];then
	    echo 1
	else
	    echo 0
	fi
	unset re
}
########################################
# 描述: 文件是否是合理图片
# 参数: $1:文件
# 返回: 1: 是；
#       0: 不是
# 实例: IsImage "xxxx.gif"
########################################
function IsImage(){
    [[ -z "$1" ]] && {
        error "Usage: IsImage <image>"
        return $INVALID_ARGUMENTS
    }
    file -i ${1} | grep -qE 'image/*' && echo 1 || echo 0
}
########################################
# 描述: 检测颜色代码字符串
# 参数: $1:颜色代码字符串，如:#ef0078,#dff
# 返回: 1: 合理；
#       0: 不合理
# 实例: IsColor "xxx"
########################################
function IsColor(){
    [[ -z "$1" ]] && {
        error "Usage: IsColor <颜色代码>"
        return $INVALID_ARGUMENTS
    }

    local re='^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$'
    if [[ ${1} =~ ${re} ]];then
        echo 1 #是颜色代码
    else
        echo 0 #不是
    fi
	unset re
}
########################################
# 描述: 检测颜色名称
# 参数: $1:颜色名称，如:blue,red,green
# 返回: 1: 合理；
#       0: 不合理
# 实例: IsColorName "xxx"
# 注意: COLORS_NAME列表中颜色名称未添加完成
########################################
function IsColorName(){
    [[ -z "$1" ]] && {
        error "Usage: IsColorName <颜色名称>"
        return $INVALID_ARGUMENTS
    }
    
    COLORS_NAME=(`echo $COLORS_NAME | awk -v RS='' '{gsub("\n"," "); print}'`)

    local color=$(lower $1)
    local ret=0
    for temp in ${COLORS_NAME[@]};do
        if [[ ${temp} = ${color} ]];then
            ret=1
            break
        fi
    done
    echo $ret
    unset color
    unset temp
    unset ret
}

########################################
# 描述: 单位转换函数
# 参数: $1,数值(kb)
# 返回: GB/MB/KB
# 实例: UnitConversion <bytes>
########################################
function UnitConversion(){
    local num=$1
    local val
    local ret

	if [[ ${num} -ge  1048576 ]];then
		val=1048576 #1024*1024	
		ret=$(awk 'BEGIN{printf"%.2f\n",'${num}' / '${val}'}') #将KB转换成GB，并保留2位小数
		printf '%s\n' ${ret}"GB"
	elif [[ ${num} -ge  1024 ]];then
		val=1024 	
		ret=$(awk 'BEGIN{printf"%.2f\n",'${num}' / '${val}'}') #将KB转换成MB，并保留2位小数
		printf '%s' ${ret}"MB"
	else
		printf '%s' ${num}"KB"
	fi
}
########################################
# 描述: 延迟操作，并计时，超时m秒将返回0
# 参数: $1,延时秒数
# 返回: 超时还回0
# 实例: delay
########################################
function delay() {
    local m=$1
    local start_time=$(date +%s)
    local end_time=$((start_time + m))
    local isn=$(IsNumber $m)
    [[ -z "$m" ]] && [[ ${isn} -ne 1 ]]&& {
        error "Usage: delay <延时秒数>"
        return $INVALID_ARGUMENTS
    }
    
    while [[ $(date +%s) -lt $end_time ]]; do
        if [[ $(($end_time - $(date +%s))) -eq 0 ]]; then
            echo 0
            return 0
        fi
        sleep 1
        printf "\r${RB_YELLOW}倒计时：${RESET}${RB_RED}$(($end_time - $(date +%s)))${RESET}"
    done
}

########################################
# 描述: 创建符号链接
# 参数: $1,目标目录;$2,链接目录;$3,符号名称
# 返回: 
# 实例: 
########################################
function create_link_to_sdcard(){
    local cur=$(pwd)
    
    [[ -z "$1" || -z "$2" || -z "$3" ]] && {
        error "Usage: create_link_to_sdcard <dst-path> <link-path> <link-name>"
        return $INVALID_ARGUMENTS
    }
    #目标目录路径
    local true_path=$1
    #链接目录路径
    local link_path=$2
    #目录名称
    local dir_name=$3

    #指向目标目录，没有就创建
    if [[ ! -d "${true_path}" ]];  then
		mkdir -p ${true_path}
	fi
	
	#符号连接目录
	if [[ ! -d "${link_path}" ]];  then
	    mkdir -p ${link_path}
	fi
	
	#创建符号连接
	cd ${link_path}
	ln -sf ${true_path} ${dir_name}
    cd ${cur}
    success "${GREEN}符号连接[${RESET}${YELLOW}${dir_name}${RESET}${RED}→${RESET}${YELLOW}${true_path}${RESET}${GREEN}]创建成功!${RESET}"
    tip "${BLUE}删除请在命令行输入:${RESET}${YELLOW} unlink ${dir_name}${RESET}"
    unset true_path
    unset link_path
    unset dir_name
    unset cur
}



function bif() {
    case $1 in
    0) false ;;
    [1-9] | [0-9][0-9] | [0-2][0-5][0-5]) true ;;
    *)
        warn "<$1>:  该值不在8位无符号整数类型范围内。可接受的值范围为0到255。您传入了一个无效值，它将返回false"
        false
        ;;
    esac
}


##♥*******以下使用return返回*********♥

function is_image(){
    [[ -s $1 ]] && {
        local filetype=$(file -i $1 | awk -F: '/^[^:]+:/ {print $2}')
        case ${filetype} in
            *image/*) return 0;;
            *) return 1;;
        esac
        unset filetype
    } || return 1
}

function is_digit() {
    local number_regex='^[0-9]+(\.[0-9]+)?$'
    [[ -n $1 ]] && [[ $1 =~ $number_regex ]] && return 0 || return 1
}

function is_number() {
    local number_regex='^[0-9]+$'
    [[ -n $1 ]] && [[ $1 =~ $number_regex ]] && return 0 || return 1
}

function is_file(){
    # -s 非空文件
    [[ -n $1 ]] && [[ -s $1 ]] && return 0 || return 1
}

function is_dir(){
    [[ -n $1 ]] && [[ -d $1 ]] && return 0 || return 1
}


########################################
# 描述: 测试是否定义了变量。
# 参数: $1:变量 
# 返回: 如果变量已定义则为0。其他情况下为1
# 实例: defined <变量名>
########################################
function defined() {
    local var_name="$1"
    # 使用declare -p命令尝试打印变量的值，如果成功则说明变量已定义
    if declare -p "$var_name" > /dev/null; then
        return 0
    else
        return 1
    fi
}

########################################
# 描述: 测试变量是否有值。
# 参数: $1:变量 
# 返回: 如果变量已定义且值的长度>0，则0。其他情况下为1
# 实例: has_value <变量名>
########################################
function has_value() {
    declare -p "$1" > /dev/null 2>&1
    if [[ $? -eq 0 && -n ${!1} ]]; then
        return 0
    else
        return 1
    fi
}

########################################
# 描述: 测试变量是否已启用
# 参数: $1:变量 
# 返回: 如果变量设置为“ y ”或“ yes ”，则为0。其他情况下为1。
# 实例: option_enabled <变量名>
########################################
function option_enabled() {
    local var="$1"
    local var_value=$(eval 'echo \$\"'${var}'\"')
    if [[ "$var_value" == "y" ]] || [[ "$var_value" == "yes" ]]; then
        return 0
    else
        return 1
    fi
}

########################################
# 描述: 测试目录是否存在。
# 参数: $1:目录 
# 返回: 如果目录存在则为0。其他情况下为1
# 实例: defined <变量名>
########################################
function directory_exists() {
    if [[ -d "$1" ]]; then
        return 0
    fi
    return 1
}

########################################
# 描述: 测试文件是否存在。
# 参数: $1:文件
# 返回: 如果文件存在则为0。其他情况下为1
# 实例: defined <变量名>
########################################
function file_exists() {
    if [[ -f "$1" ]]; then
        return 0
    fi
    return 1
}







__base_init__










































